﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using ParentChildLookup.Tools;
using System.Data;
using System.Collections;
using Microsoft.SharePoint.Utilities;
using ParentChildLookup.Data;
using System.Web.UI;
using ParentChildLookup.BO;

namespace ParentChildLookup.Pages
{
    public partial class ManageLinkedColumns : LayoutsPageBase
    {
        protected DataTable SourceTable;

        protected override SPBasePermissions RightsRequired
        {
            get
            {
                return (SPBasePermissions.EmptyMask | SPBasePermissions.ManageLists);
            }
        }

        public string CurrentObjectId
        {
            get
            {
                string queryString = this.Page.Request["ObjectId"];
                if (string.IsNullOrEmpty(queryString))
                    throw new SPException("Parameters are missing.");

                return queryString;
            }
        }

        public SPData.Enumerations.ObjectType CurrentObjectType
        {
            get
            {
                string queryString = this.Page.Request["ObjectType"];
                if (string.IsNullOrEmpty(queryString))
                    throw new SPException("Parameters are missing.");

                SPData.Enumerations.ObjectType retType = SPData.Enumerations.ObjectType.ContentType;

                if (queryString == SPData.Enumerations.ObjectType.ContentType.ToString())
                    retType = SPData.Enumerations.ObjectType.ContentType;
                else if (queryString == SPData.Enumerations.ObjectType.List.ToString())
                    retType = SPData.Enumerations.ObjectType.List;


                return retType;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            if (!Page.IsPostBack)
            {
                SourceTable = new DataTable();
                SourceTable.Columns.Add(new DataColumn("Title", typeof(string)));
                SourceTable.Columns.Add(new DataColumn("InternalName", typeof(string)));
                SourceTable.Columns.Add(new DataColumn("CurrentLink", typeof(string)));

                switch (CurrentObjectType)
                {
                    case SPData.Enumerations.ObjectType.List:
                        Guid listGuid = new Guid(CurrentObjectId);
                        SPList selectedList = base.Web.Lists[listGuid];
                        List<string> ctIds = new List<string>();
                        foreach (SPContentType contentType in selectedList.ContentTypes)
                        {
                            ctIds.Add(contentType.Id.ToString());
                        }
                        BindSourceTable(selectedList.Fields, ctIds);

                        break;
                    case SPData.Enumerations.ObjectType.ContentType:
                        SPContentTypeId ctId = new SPContentTypeId(CurrentObjectId.ToLower());
                        SPContentType ct = base.Web.ContentTypes[ctId];
                        BindSourceTable(ct.Fields, new List<string> { ctId.ToString() });
                        break;
                    default:
                        break;
                }
            }

            (btnSave as ToolBarButton).Click += new EventHandler(btnSave_Click);
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            foreach (RepeaterItem item in RptListOfLookupFields.Items)
            {
                Literal ltTitle = item.FindControl("ltTitle") as Literal;
                Literal ltInternalName = item.FindControl("ltInternalName") as Literal;
                DropDownList ddlLookups = item.FindControl("ddlLookups") as DropDownList;
                CheckBox chkSelected = item.FindControl("chkSelected") as CheckBox;

                switch (CurrentObjectType)
                {
                    case SPData.Enumerations.ObjectType.List:
                        Guid listGuid = new Guid(CurrentObjectId);
                        SPList selectedList = base.Web.Lists[listGuid];
                        foreach (SPContentType contentType in selectedList.ContentTypes)
                        {
                            if (!contentType.Sealed)
                            {
                                AddLinkedField(contentType, ltInternalName.Text, ddlLookups.SelectedValue, chkSelected.Checked);
                                UpdateContentTypeFormTemplate(contentType);
                            }
                        }
                        break;
                    case SPData.Enumerations.ObjectType.ContentType:
                        SPContentTypeId ctId = new SPContentTypeId(CurrentObjectId.ToLower());
                        SPContentType ct = base.Web.ContentTypes[ctId];
                        AddLinkedField(ct, ltInternalName.Text, ddlLookups.SelectedValue, chkSelected.Checked);
                        UpdateContentTypeFormTemplate(ct);
                        break;
                }
            }
        }


        protected override void OnLoad(EventArgs e)
        {
            string pageTitle = SPTools.GetParentChildLookupResource("Page_ManageLinkedColumn", base.Web);
            switch (CurrentObjectType)
            {
                case SPData.Enumerations.ObjectType.List:
                    Guid listGuid = new Guid(CurrentObjectId);
                    SPList selectedList = base.Web.Lists[listGuid];
                    pageTitle = string.Format("{0} de : {1}", pageTitle, selectedList.Title);
                    break;
                case SPData.Enumerations.ObjectType.ContentType:
                    SPContentTypeId ctId = new SPContentTypeId(CurrentObjectId.ToLower());
                    SPContentType ct = base.Web.ContentTypes[ctId];
                    pageTitle = string.Format("{0} de : {1}", pageTitle, ct.Name);
                    break;
                default:
                    break;
            }
            ltPageTitle.Text = pageTitle;
            ltPageTitleInTitle.Text = pageTitle;
            ltPageDescription.Text = SPTools.GetParentChildLookupResource("Page_ManageLinkedColumn_Desc", base.Web);
            ltLookupField.Text = SPTools.GetParentChildLookupResource("Page_LookupField", base.Web);
            ltLookupLink.Text = SPTools.GetParentChildLookupResource("Page_LookupLink", base.Web);
            ltSelected.Text = SPTools.GetParentChildLookupResource("Page_LookupSelected", base.Web);


            (btnSave as ToolBarButton).Text = SPTools.GetParentChildLookupResource("Page_Save", base.Web);
            (btnCancel as ToolBarButton).Text = SPTools.GetParentChildLookupResource("Page_Cancel", base.Web);
        }

        protected void RptListOfLookupFields_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Literal ltTitle = e.Item.FindControl("ltTitle") as Literal;
                Literal ltInternalName = e.Item.FindControl("ltInternalName") as Literal;
                DropDownList ddlLookups = e.Item.FindControl("ddlLookups") as DropDownList;
                CheckBox chkSelected = e.Item.FindControl("chkSelected") as CheckBox;

                ltTitle.Text = DataBinder.Eval(e.Item.DataItem, "Title").ToString();
                ltInternalName.Text = DataBinder.Eval(e.Item.DataItem, "InternalName").ToString();
                if (DataBinder.Eval(e.Item.DataItem, "CurrentLink") != null)
                {
                    ddlLookups.SelectedValue = DataBinder.Eval(e.Item.DataItem, "CurrentLink").ToString();
                    chkSelected.Checked = !string.IsNullOrEmpty(DataBinder.Eval(e.Item.DataItem, "CurrentLink").ToString());
                }
            }
        }

        private void BindSourceTable(SPFieldCollection sPFieldCollection, List<string> contentTypeIds)
        {

            List<ParentChildLookupBO> parentChildLookupList = new List<ParentChildLookupBO>();

            foreach (string ctId in contentTypeIds)
            {
                ParentChildLookupBO pcl = SPTools.DeSerializeParentChildLookup(base.Web.Properties[ctId]);
                if (pcl != null)
                    parentChildLookupList.Add(pcl);
            }

            foreach (SPField field in sPFieldCollection)
            {
                if (field.Type == SPFieldType.Lookup && !field.Hidden)
                {
                    DataRow row = SourceTable.NewRow();
                    row["Title"] = field.Title;
                    row["InternalName"] = field.InternalName;

                    string currentLink = string.Empty;
                    foreach (ParentChildLookupBO parentChildLookup in parentChildLookupList)
                    {
                        if (parentChildLookup.ChildFields.Contains(field.InternalName))
                            currentLink = parentChildLookup.ParentFieldInternalName;
                    }

                    row["CurrentLink"] = currentLink;
                    SourceTable.Rows.Add(row);
                }
            }

            RptListOfLookupFields.DataSource = SourceTable;
            RptListOfLookupFields.DataBind();
        }

        private void AddLinkedField(SPContentType contentType, string lookupToLink, string lookupParent, bool toAdd)
        {
            UpdateWebProperties(contentType.Id.ToString(), lookupToLink, lookupParent, toAdd);
        }

        private void UpdateContentTypeFormTemplate(SPContentType contentType)
        {
            contentType.EditFormTemplateName = "LinkedLookupListForm";
            contentType.NewFormTemplateName = "LinkedLookupListForm";
            contentType.Update();
        }

        private void UpdateWebProperties(string contentTypeId, string lookupToLink, string lookupParent, bool toAdd)
        {
            using (SPSite site = new SPSite(base.Web.Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    if (toAdd)
                        SPTools.AddParentChildList(web, contentTypeId, lookupParent, lookupToLink);
                    else
                        SPTools.RemoveParentChild(web, contentTypeId, lookupToLink);
                }
            }
        }
    }
}
